package jnpf.permission.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.xuyanwu.spring.file.storage.FileInfo;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.ImmutableList;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jnpf.annotation.PositionPermission;
import jnpf.base.ActionResult;
import jnpf.base.controller.SuperController;
import jnpf.base.entity.DictionaryDataEntity;
import jnpf.base.service.DictionaryDataService;
import jnpf.base.vo.DownloadVO;
import jnpf.base.vo.ListVO;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.config.ConfigValueUtil;
import jnpf.constant.MsgCode;
import jnpf.constant.PermissionConst;
import jnpf.exception.DataException;
import jnpf.model.ExcelColumnAttr;
import jnpf.model.ExcelImportForm;
import jnpf.model.ExcelImportVO;
import jnpf.model.ExcelModel;
import jnpf.permission.constant.PosColumnMap;
import jnpf.permission.entity.*;
import jnpf.permission.model.check.CheckResult;
import jnpf.permission.model.permission.PermissionModel;
import jnpf.permission.model.position.*;
import jnpf.permission.model.user.mod.UserIdModel;
import jnpf.permission.service.*;
import jnpf.permission.util.ExcelTool;
import jnpf.util.*;
import jnpf.util.enums.DictionaryDataEnum;
import jnpf.util.treeutil.ListToTreeUtil;
import jnpf.util.treeutil.SumTree;
import jnpf.util.treeutil.newtreeutil.TreeDotUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 岗位信息
 *
 * @author JNPF开发平台组
 * @version V3.1.0
 * @copyright 引迈信息技术有限公司
 * @date 2019年9月26日 上午9:18
 */
@Tag(name = "岗位管理", description = "Position")
@RestController
@RequestMapping("/api/permission/Position")
public class PositionController extends SuperController<PositionService, PositionEntity> {
    @Autowired
    private UserRelationService userRelationService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private PositionService positionService;
    @Autowired
    private OrganizeService organizeService;
    @Autowired
    private DictionaryDataService dictionaryDataService;
    @Autowired
    private OrganizeRelationService organizeRelationService;
    @Autowired
    private ConfigValueUtil configValueUtil;

    /**
     * 获取岗位管理信息列表
     *
     * @param paginationPosition 分页模型
     * @return
     */
    @Operation(summary = "获取岗位列表（分页）")
    @SaCheckPermission("permission.position")
    @GetMapping
    public ActionResult<PageListVO<PositionListVO>> list(PaginationPosition paginationPosition) {
        List<DictionaryDataEntity> dictionaryDataEntities = dictionaryDataService.getListByTypeDataCode(DictionaryDataEnum.POSITION_TYPE.getDictionaryTypeId());
        if (StringUtil.isNotEmpty(paginationPosition.getType())) {
            DictionaryDataEntity dictionaryDataEntity = dictionaryDataEntities.stream().filter(t -> paginationPosition.getType().equals(t.getId())).findFirst().orElse(null);
            if (dictionaryDataEntity != null) {
                paginationPosition.setEnCode(dictionaryDataEntity.getEnCode());
            }
        }
        List<PositionEntity> data = positionService.getList(paginationPosition);
        //添加部门信息，部门映射到organizeId
        List<PositionListVO> voList = JsonUtil.getJsonToList(data, PositionListVO.class);
        List<String> collect = data.stream().map(PositionEntity::getOrganizeId).collect(Collectors.toList());
        List<OrganizeEntity> list = organizeService.getOrgEntityList(collect, true);
        //添加部门信息
        Map<String, String> orgIdNameMaps = organizeService.getInfoList();
        for (PositionListVO entity1 : voList) {
            OrganizeEntity entity = list.stream().filter(t -> t.getId().equals(entity1.getOrganizeId())).findFirst().orElse(new OrganizeEntity());
            if (entity1.getOrganizeId().equals(entity.getId())) {
                entity1.setDepartment(organizeService.getFullNameByOrgIdTree(orgIdNameMaps, entity.getOrganizeIdTree(), "/"));
            }
        }
        //将type成中文名
        for (PositionListVO entity1 : voList) {
            dictionaryDataEntities.stream().filter(t -> t.getEnCode().equals(entity1.getType())).findFirst().ifPresent(entity -> entity1.setType(entity.getFullName()));
        }
        PaginationVO paginationVO = JsonUtil.getJsonToBean(paginationPosition, PaginationVO.class);
        return ActionResult.page(voList, paginationVO);
    }

    /**
     * 列表
     *
     * @return
     */
    @Operation(summary = "列表")
    @GetMapping("/All")
    public ActionResult<ListVO<PositionListAllVO>> listAll() {
        List<PositionEntity> list = positionService.getList(true);
        List<PositionListAllVO> vos = JsonUtil.getJsonToList(list, PositionListAllVO.class);
        ListVO<PositionListAllVO> vo = new ListVO<>();
        vo.setList(vos);
        return ActionResult.success(vo);
    }

    /**
     * 树形（机构+岗位）
     *
     * @return
     */
    @Operation(summary = "获取岗位下拉列表（公司+部门+岗位）")
    @GetMapping("/Selector")
    public ActionResult<ListVO<PositionSelectorVO>> selector() {
        List<PositionEntity> list1 = positionService.getList(true);
        Map<String, OrganizeEntity> orgMaps = organizeService.getOrgMaps(null, false, null);
        Map<String, String> orgIdNameMaps = organizeService.getInfoList();
        List<OrganizeEntity> list2 = new ArrayList<>(orgMaps.values());
        ;
        List<PosOrgModel> posList = new ArrayList<>();
        for (PositionEntity entity : list1) {
            PosOrgModel posOrgModel = JsonUtil.getJsonToBean(entity, PosOrgModel.class);
            String organizeId = entity.getOrganizeId();
            posOrgModel.setParentId(organizeId);
            posOrgModel.setType("position");
            posOrgModel.setIcon("icon-ym icon-ym-tree-position1");
            OrganizeEntity organizeEntity = orgMaps.get(organizeId);
            if (organizeEntity != null) {
                posOrgModel.setOrganize(organizeService.getFullNameByOrgIdTree(orgIdNameMaps, organizeEntity.getOrganizeIdTree(), "/"));
                posOrgModel.setOrganizeIds(organizeService.getOrgIdTree(organizeEntity));
            } else {
                posOrgModel.setOrganizeIds(new ArrayList<>());
            }
            posList.add(posOrgModel);
        }
        List<PosOrgModel> orgList = JsonUtil.getJsonToList(list2, PosOrgModel.class);
        for (PosOrgModel entity1 : orgList) {
            if ("department".equals(entity1.getType())) {
                entity1.setIcon("icon-ym icon-ym-tree-department1");
            } else if ("company".equals(entity1.getType())) {
                entity1.setIcon("icon-ym icon-ym-tree-organization3");
            }
            OrganizeEntity organizeEntity = orgMaps.get(entity1.getId());
            if (organizeEntity != null) {
                entity1.setOrganize(organizeService.getFullNameByOrgIdTree(orgIdNameMaps, organizeEntity.getOrganizeIdTree(), "/"));
                entity1.setOrganizeIds(organizeService.getOrgIdTree(organizeEntity));
            } else {
                entity1.setOrganizeIds(new ArrayList<>());
            }
            entity1.setOrganizeIds(new ArrayList<>());
        }
        JSONArray objects = ListToTreeUtil.treeWhere(posList, orgList);
        List<PosOrgModel> jsonToList = JsonUtil.getJsonToList(objects, PosOrgModel.class);

        List<PosOrgModel> list = new ArrayList<>(16);
        // 得到角色的值
        List<PosOrgModel> collect = jsonToList.stream().filter(t -> "position".equals(t.getType())).sorted(Comparator.comparing(PosOrgModel::getSortCode)).collect(Collectors.toList());
        list.addAll(collect);
        jsonToList.removeAll(collect);
        List<PosOrgModel> collect1 = jsonToList.stream().sorted(Comparator.comparing(PosOrgModel::getSortCode).thenComparing(PosOrgModel::getCreatorTime, Comparator.reverseOrder())).collect(Collectors.toList());
        list.addAll(collect1);

        List<SumTree<PosOrgModel>> trees = TreeDotUtils.convertListToTreeDot(list);
        List<PositionSelectorVO> jsonToList1 = JsonUtil.getJsonToList(trees, PositionSelectorVO.class);
        ListVO vo = new ListVO();
        vo.setList(jsonToList1);
        return ActionResult.success(vo);
    }

    /**
     * 通过部门、岗位获取岗位下拉框
     *
     * @param idModel 岗位选择模型
     * @return
     */
    @Operation(summary = "通过部门、岗位获取岗位下拉框")
    @Parameters({
            @Parameter(name = "positionConditionModel", description = "岗位选择模型", required = true)
    })
    @PostMapping("/PositionCondition")
    public ActionResult<ListVO<PositionSelectorVO>> positionCondition(@RequestBody UserIdModel idModel) {
        // 定义返回对象
        List<PositionSelectorVO> modelList = new ArrayList<>();

        List<String> list = organizeRelationService.getOrgIds(idModel.getIds(), null);
        List<String> lists = new ArrayList<>();
        list.forEach(t -> lists.add(t.split("--")[0]));
        list = lists;
        List<String> collect = positionService.getListByOrganizeId(list, false).stream().map(PositionEntity::getId).collect(Collectors.toList());
        collect.addAll(list);
        List<PositionEntity> positionName = positionService.getPositionName(collect, null);
        positionName = positionName.stream().filter(t -> "1".equals(String.valueOf(t.getEnabledMark()))).collect(Collectors.toList());

        Map<String, OrganizeEntity> orgMaps = organizeService.getOrganizeName(positionName.stream().map(PositionEntity::getOrganizeId).collect(Collectors.toList()), null, false, null);
        Map<String, String> orgIdNameMaps = organizeService.getInfoList();

        List<PosOrgConditionModel> posOrgModels = new ArrayList<>(16);
        positionName.forEach(t -> {
            PosOrgConditionModel posOrgModel = JsonUtil.getJsonToBean(t, PosOrgConditionModel.class);
            OrganizeEntity entity = orgMaps.get(t.getOrganizeId());
            if (entity != null) {
                posOrgModel.setOrganizeId(entity.getId());
                posOrgModel.setParentId(entity.getId());
                if (StringUtil.isNotEmpty(entity.getOrganizeIdTree())) {
                    posOrgModel.setOrganize(organizeService.getFullNameByOrgIdTree(orgIdNameMaps, entity.getOrganizeIdTree(), "/"));
                }
            }
            posOrgModel.setType("position");
            posOrgModel.setIcon("icon-ym icon-ym-tree-position1");
            posOrgModels.add(posOrgModel);
        });

        // 处理组织
        orgMaps.values().forEach(org -> {
            PosOrgConditionModel orgVo = JsonUtil.getJsonToBean(org, PosOrgConditionModel.class);
            if ("department".equals(orgVo.getType())) {
                orgVo.setIcon("icon-ym icon-ym-tree-department1");
            } else if ("company".equals(orgVo.getType())) {
                orgVo.setIcon("icon-ym icon-ym-tree-organization3");
            }
            // 处理断层
            if (StringUtil.isNotEmpty(org.getOrganizeIdTree())) {
                List<String> list1 = new ArrayList<>();
                String[] split = org.getOrganizeIdTree().split(",");
                list1 = Arrays.asList(split);
                Collections.reverse(list1);
                for (String orgId : list1) {
                    OrganizeEntity organizeEntity1 = orgMaps.get(orgId);
                    if (organizeEntity1 != null && !organizeEntity1.getId().equals(orgVo.getId())) {
                        orgVo.setParentId(organizeEntity1.getId());
                        String[] split1 = org.getOrganizeIdTree().split(organizeEntity1.getId());
                        if (split1.length > 1) {
                            orgVo.setFullName(organizeService.getFullNameByOrgIdTree(orgIdNameMaps, split1[1], "/"));
                        }
                        break;
                    }
                }
            }
            posOrgModels.add(orgVo);
        });

        List<SumTree<PosOrgConditionModel>> trees = TreeDotUtils.convertListToTreeDot(posOrgModels);
        List<PositionSelectorVO> positionSelectorVO = JsonUtil.getJsonToList(trees, PositionSelectorVO.class);
        // 处理数据
        positionSelectorVO.forEach(t -> {
            if (!"position".equals(t.getType())) {
                t.setFullName(organizeService.getFullNameByOrgIdTree(orgIdNameMaps, t.getOrganizeIdTree(), "/"));
            }
        });
        modelList.addAll(positionSelectorVO);
        ListVO vo = new ListVO();
        vo.setList(modelList);
        return ActionResult.success(vo);
    }

    /**
     * 通过组织id获取岗位列表
     *
     * @param organizeId 主键值
     * @return
     */
    @Operation(summary = "通过组织id获取岗位列表")
    @Parameters({
            @Parameter(name = "organizeId", description = "主键值", required = true)
    })
    @SaCheckPermission("permission.position")
    @GetMapping("/getList/{organizeId}")
    public ActionResult<List<PositionVo>> getListByOrganizeId(@PathVariable("organizeId") String organizeId) {
        List<PositionEntity> list = positionService.getListByOrganizeId(Collections.singletonList(organizeId), false);
        List<PositionVo> jsonToList = JsonUtil.getJsonToList(list, PositionVo.class);
        return ActionResult.success(jsonToList);
    }

    /**
     * 获取岗位管理信息
     *
     * @param id 主键值
     * @return
     */
    @Operation(summary = "获取岗位管理信息")
    @Parameters({
            @Parameter(name = "id", description = "主键值", required = true)
    })
    @SaCheckPermission("permission.position")
    @GetMapping("/{id}")
    public ActionResult<PositionInfoVO> getInfo(@PathVariable("id") String id) throws DataException {
        PositionEntity entity = positionService.getInfo(id);
        PositionInfoVO vo = JsonUtilEx.getJsonToBeanEx(entity, PositionInfoVO.class);
        String organizeId = entity.getOrganizeId();
        OrganizeEntity organizeEntity = organizeService.getInfo(organizeId);
        vo.setOrganizeIdTree(StringUtil.isNotEmpty(organizeEntity.getOrganizeIdTree()) ? Arrays.asList(organizeEntity.getOrganizeIdTree().split(",")) : new ArrayList<>());
        return ActionResult.success(vo);
    }


    /**
     * 新建岗位管理
     *
     * @param positionCrForm 实体对象
     * @return
     */
    @PositionPermission
    @Operation(summary = "新建岗位管理")
    @Parameters({
            @Parameter(name = "positionCrForm", description = "实体对象", required = true)
    })
    @SaCheckPermission("permission.position")
    @PostMapping
    public ActionResult create(@RequestBody @Valid PositionCrForm positionCrForm) {
        PositionEntity entity = JsonUtil.getJsonToBean(positionCrForm, PositionEntity.class);
        if (positionService.isExistByFullName(entity, false)) {
            return ActionResult.fail(MsgCode.EXIST001.get());
        }
        if (positionService.isExistByEnCode(entity, false)) {
            return ActionResult.fail(MsgCode.EXIST002.get());
        }
        // 设置岗位id
        entity.setId(RandomUtil.uuId());
//        createOrganizeRoleRelation(entity.getOrganizeId(), entity.getId());
        positionService.create(entity);
        return ActionResult.success(MsgCode.SU001.get());
    }

    /**
     * 更新岗位管理
     *
     * @param id             主键值
     * @param positionUpForm 实体对象
     * @return
     */
    @PositionPermission
    @Operation(summary = "更新岗位管理")
    @Parameters({
            @Parameter(name = "id", description = "主键值", required = true),
            @Parameter(name = "positionUpForm", description = "实体对象", required = true)
    })
    @SaCheckPermission("permission.position")
    @PutMapping("/{id}")
    public ActionResult update(@PathVariable("id") String id, @RequestBody @Valid PositionUpForm positionUpForm) {
        PositionEntity positionEntity = positionService.getInfo(id);
        if (positionEntity == null) {
            return ActionResult.fail(MsgCode.FA003.get());
        }
        // 当岗位绑定用户不让其更改
        if (userRelationService.existByObj(PermissionConst.POSITION, id)) {
            if (!positionService.getInfo(id).getOrganizeId().equals(positionUpForm.getOrganizeId())) {
                return ActionResult.fail(MsgCode.FA023.get());
            }
            if (positionUpForm.getEnabledMark() == 0 && positionEntity.getEnabledMark() == 1) {
                return ActionResult.fail(MsgCode.FA030.get());
            }
        }
        PositionEntity entity = JsonUtil.getJsonToBean(positionUpForm, PositionEntity.class);
        entity.setId(id);
        if (positionService.isExistByFullName(entity, true)) {
            return ActionResult.fail(MsgCode.EXIST001.get());
        }
        if (positionService.isExistByEnCode(entity, true)) {
            return ActionResult.fail(MsgCode.EXIST002.get());
        }
//        createOrganizeRoleRelation(entity.getOrganizeId(), id);
        boolean flag = positionService.update(id, entity);
        if (flag == false) {
            return ActionResult.fail(MsgCode.FA002.get());
        }
        return ActionResult.success(MsgCode.SU004.get());
    }

    /**
     * 删除岗位管理
     *
     * @param id 主键值
     * @return
     */
    @PositionPermission
    @Operation(summary = "删除岗位管理")
    @Parameters({
            @Parameter(name = "id", description = "主键值", required = true)
    })
    @SaCheckPermission("permission.position")
    @DeleteMapping("/{id}")
    public ActionResult delete(@PathVariable("id") String id) {
        // 当岗位绑定用户不让其更改
        if (userRelationService.existByObj(PermissionConst.POSITION, id)) {
            return ActionResult.fail(MsgCode.FA024.get());
        }
        PositionEntity entity = positionService.getInfo(id);
        if (entity != null) {
            List<UserRelationEntity> userRelList = userRelationService.getListByObjectId(id);
            if (userRelList.size() > 0) {
                return ActionResult.fail(MsgCode.FA024.get());
            }
            for (UserRelationEntity entity1 : userRelList) {
                UserEntity entity2 = userService.getById(entity1.getUserId());
                if (entity2 != null) {
                    String newPositionId = entity2.getPositionId().replace(id, "");
                    if (entity2.getPositionId().contains(id)) {
                        if (newPositionId.length() != 0 && newPositionId.substring(0, 1).equals(",")) {
                            entity2.setPositionId(newPositionId.substring(1));
                        } else if (newPositionId.length() != 0) {
                            entity2.setPositionId(newPositionId.replace(",,", ","));
                        }
                    }
                }
            }
            userRelationService.deleteAllByObjId(id);

            // 删除岗位与组织之间的关联数据
            QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
            query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.POSITION);
            query.lambda().eq(OrganizeRelationEntity::getObjectId, id);
            organizeRelationService.remove(query);

            positionService.delete(entity);
            return ActionResult.success(MsgCode.SU003.get());
        }
        return ActionResult.fail(MsgCode.FA003.get());
    }

    /**
     * 更新菜单状态
     *
     * @param id 主键值
     * @return
     */
    @Operation(summary = "更新菜单状态")
    @Parameters({
            @Parameter(name = "id", description = "主键值", required = true)
    })
    @SaCheckPermission("permission.position")
    @PutMapping("/{id}/Actions/State")
    public ActionResult upState(@PathVariable("id") String id) {
        PositionEntity entity = positionService.getInfo(id);
        if (entity != null) {
            if (entity.getEnabledMark() == null || "1".equals(String.valueOf(entity.getEnabledMark()))) {
                entity.setEnabledMark(0);
            } else {
                entity.setEnabledMark(1);
            }
            positionService.update(id, entity);
            return ActionResult.success(MsgCode.SU004.get());
        }
        return ActionResult.fail(MsgCode.FA001.get());
    }

    /**
     * 通过组织id获取岗位列表
     *
     * @param organizeIds 组织id数组
     * @return 岗位列表
     */
    @Operation(summary = "获取岗位列表通过组织id数组")
    @Parameters({
            @Parameter(name = "organizeIds", description = "组织id数组", required = true)
    })
    @SaCheckPermission("permission.position")
    @PostMapping("/getListByOrgIds")
    public ActionResult<ListVO<PermissionModel>> getListByOrganizeIds(@RequestBody @Valid Map<String, List<String>> organizeIds) {
        List<PermissionModel> PositionModelAll = new LinkedList<>();
        if (organizeIds.get("organizeIds") != null) {
            List<String> ids = ImmutableList.of("0");
            PositionModelAll = positionService.getListByOrganizeIds(ids, false,true);
        }
        ListVO vo = new ListVO();
        vo.setList(PositionModelAll);
        return ActionResult.success(vo);
    }

    /**
     * 添加组织角色关联关系
     *
     * @param organizeId 组织id
     * @param positionId 岗位id
     */
    private void createOrganizeRoleRelation(String organizeId, String positionId) {
        // 清除之前的关联关系
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.POSITION);
        query.lambda().eq(OrganizeRelationEntity::getObjectId, positionId);
        organizeRelationService.remove(query);
        // 添加与组织的关联关系
        OrganizeRelationEntity organizeRelationEntity = new OrganizeRelationEntity();
        organizeRelationEntity.setId(RandomUtil.uuId());
        organizeRelationEntity.setOrganizeId(organizeId);
        organizeRelationEntity.setObjectType(PermissionConst.POSITION);
        organizeRelationEntity.setObjectId(positionId);
        organizeRelationService.save(organizeRelationEntity);
    }


    /**
     * 模板下载
     *
     * @return
     */
    @Operation(summary = "模板下载")
    @SaCheckPermission("permission.position")
    @GetMapping("/TemplateDownload")
    public ActionResult<DownloadVO> TemplateDownload() {
        PosColumnMap columnMap = new PosColumnMap();
        String excelName = columnMap.getExcelName();
        Map<String, String> keyMap = columnMap.getColumnByType(0);
        List<ExcelColumnAttr> models = columnMap.getFieldsModel(false);
        List<Map<String, Object>> list = columnMap.getDefaultList();
        Map<String, String[]> optionMap = getOptionMap();
        ExcelModel excelModel = ExcelModel.builder().models(models).selectKey(new ArrayList<>(keyMap.keySet())).optionMap(optionMap).build();
        DownloadVO vo = ExcelTool.getImportTemplate(configValueUtil.getTemporaryFilePath(), excelName, keyMap, list, excelModel);
        return ActionResult.success(vo);
    }

    /**
     * 上传Excel
     *
     * @return
     */
    @Operation(summary = "上传导入Excel")
    @SaCheckPermission("permission.position")
    @PostMapping("/Uploader")
    public ActionResult<Object> Uploader() {
        return ExcelTool.uploader();
    }

    /**
     * 导入预览
     *
     * @return
     */
    @Operation(summary = "导入预览")
    @SaCheckPermission("permission.position")
    @GetMapping("/ImportPreview")
    public ActionResult<Map<String, Object>> ImportPreview(String fileName) throws Exception {
        // 导入字段
        PosColumnMap columnMap = new PosColumnMap();
        Map<String, String> keyMap = columnMap.getColumnByType(0);
        Map<String, Object> headAndDataMap = ExcelTool.importPreview(configValueUtil.getTemporaryFilePath(), fileName, keyMap);
        return ActionResult.success(headAndDataMap);
    }

    /**
     * 导出异常报告
     *
     * @return
     */
    @Operation(summary = "导出异常报告")
    @SaCheckPermission("permission.position")
    @PostMapping("/ExportExceptionData")
    public ActionResult<DownloadVO> ExportExceptionData(@RequestBody ExcelImportForm visualImportModel) {
        String temporaryFilePath = configValueUtil.getTemporaryFilePath();
        List<Map<String, Object>> dataList = visualImportModel.getList();
        PosColumnMap columnMap = new PosColumnMap();
        String excelName = columnMap.getExcelName();
        Map<String, String> keyMap = columnMap.getColumnByType(0);
        List<ExcelColumnAttr> models = columnMap.getFieldsModel(true);
        ExcelModel excelModel = ExcelModel.builder().optionMap(getOptionMap()).models(models).build();
        DownloadVO vo = ExcelTool.exportExceptionReport(temporaryFilePath, excelName, keyMap, dataList, excelModel);
        return ActionResult.success(vo);
    }

    /**
     * 导入数据
     *
     * @return
     */
    @Operation(summary = "导入数据")
    @SaCheckPermission("permission.position")
    @PostMapping("/ImportData")
    public ActionResult<ExcelImportVO> ImportData(@RequestBody ExcelImportForm visualImportModel) throws Exception {
        List<Map<String, Object>> listData = visualImportModel.getList();
        List<PositionEntity> addList = new ArrayList<PositionEntity>();
        List<Map<String, Object>> failList = new ArrayList<>();
        // 对数据做校验
        this.validateImportData(listData, addList, failList);

        //正常数据插入
        for (PositionEntity each : addList) {
            positionService.create(each);
        }
        ExcelImportVO importModel = new ExcelImportVO();
        importModel.setSnum(addList.size());
        importModel.setFnum(failList.size());
        importModel.setResultType(failList.size() > 0 ? 1 : 0);
        importModel.setFailResult(failList);
        return ActionResult.success(importModel);
    }

    /**
     * 导出Excel
     *
     * @return
     */
    @Operation(summary = "导出Excel")
    @SaCheckPermission("permission.position")
    @GetMapping("/ExportData")
    public ActionResult ExportData(PaginationPosition paginationPosition) throws IOException {
        if (StringUtil.isEmpty(paginationPosition.getSelectKey())) {
            return ActionResult.fail("请选择导出字段");
        }
        List<DictionaryDataEntity> dictionaryDataEntities = dictionaryDataService.getListByTypeDataCode(DictionaryDataEnum.POSITION_TYPE.getDictionaryTypeId());
        if (StringUtil.isNotEmpty(paginationPosition.getType())) {
            DictionaryDataEntity dictionaryDataEntity = dictionaryDataEntities.stream().filter(t -> paginationPosition.getType().equals(t.getId())).findFirst().orElse(null);
            if (dictionaryDataEntity != null) {
                paginationPosition.setEnCode(dictionaryDataEntity.getEnCode());
            }
        }
        List<PositionEntity> dataList = positionService.getList(paginationPosition);
        //组织部门
        List<String> collect = dataList.stream().map(PositionEntity::getOrganizeId).collect(Collectors.toList());
        List<OrganizeEntity> list = organizeService.getOrgEntityList(collect, true);
        Map<String, String> orgIdNameMaps = organizeService.getInfoList();

        List<Map<String, Object>> realList = new ArrayList<>();
        for (PositionEntity entity : dataList) {
            Map<String, Object> positionMap = JsonUtil.entityToMap(entity);
            //组织
            OrganizeEntity organizeEntity = list.stream().filter(t -> t.getId().equals(entity.getOrganizeId())).findFirst().orElse(new OrganizeEntity());
            if (entity.getOrganizeId().equals(organizeEntity.getId())) {
                positionMap.put("organizeId", organizeService.getFullNameByOrgIdTree(orgIdNameMaps, organizeEntity.getOrganizeIdTree(), "/"));
            }
            //岗位类型
            DictionaryDataEntity dictionaryDataEntity = dictionaryDataEntities.stream().filter(t -> t.getEnCode().equals(entity.getType()) && "1".equals(String.valueOf(t.getEnabledMark())) && t.getDeleteMark() == null).findFirst().orElse(null);
            if (dictionaryDataEntity != null) {
                positionMap.put("type", dictionaryDataEntity.getFullName());
            } else {
                positionMap.put("type", "");
            }
            positionMap.put("enabledMark", "1".equals(String.valueOf(entity.getEnabledMark())) ? "启用" : "禁用");
            realList.add(positionMap);
        }
        String[] keys = !StringUtil.isEmpty(paginationPosition.getSelectKey()) ? paginationPosition.getSelectKey() : new String[0];
        PosColumnMap posColumnMap = new PosColumnMap();
        String excelName = posColumnMap.getExcelName();
        List<ExcelColumnAttr> models = posColumnMap.getFieldsModel(false);
        Map<String, String> keyMap = posColumnMap.getColumnByType(null);
        ExcelModel excelModel = ExcelModel.builder().selectKey(Arrays.asList(keys)).models(models).optionMap(null).build();
        DownloadVO vo = ExcelTool.creatModelExcel(configValueUtil.getTemporaryFilePath(), excelName, keyMap, realList, excelModel);
        return ActionResult.success(vo);
    }

    private void validateImportData(List<Map<String, Object>> listData, List<PositionEntity> addList, List<Map<String, Object>> failList) {
        PosColumnMap columnMap = new PosColumnMap();
        Map<String, String> keyMap = columnMap.getColumnByType(0);
        QueryWrapper<PositionEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().isNull(PositionEntity::getDeleteMark);
        queryWrapper.lambda().orderByAsc(PositionEntity::getSortCode).orderByDesc(PositionEntity::getCreatorTime);
        List<PositionEntity> allPositionList = positionService.list(queryWrapper);
        List<DictionaryDataEntity> typeDictionaryList = dictionaryDataService.getListByTypeDataCode(DictionaryDataEnum.POSITION_TYPE.getDictionaryTypeId());
        Map<String, Object> allOrgsTreeName = organizeService.getAllOrgsTreeName();
        for (int i = 0, len = listData.size(); i < len; i++) {
            Map<String, Object> eachMap = listData.get(i);
            Map<String, Object> realMap = JsonUtil.getJsonToBean(eachMap, Map.class);
            StringJoiner errInfo = new StringJoiner(",");
            boolean checkOrganizeIdPass = false;
            for (String column : keyMap.keySet()) {
                Object valueObj = eachMap.get(column);
                String value = valueObj == null ? null : String.valueOf(valueObj);
                String columnName = keyMap.get(column);
                switch (column) {
                    case "organizeId":
                        if (StringUtil.isEmpty(value)) {
                            errInfo.add(columnName + "不能为空");
                            break;
                        }
                        CheckResult organizeIdCheckResult = checkOrganizeId(value, allOrgsTreeName);
                        if (!organizeIdCheckResult.isPass()) {
                            errInfo.add("找不到该所属组织");
                            break;
                        }
                        realMap.put("organizeId", organizeIdCheckResult.getValue());
                        checkOrganizeIdPass = true;
                        break;
                    case "fullName":
                        if (StringUtil.isEmpty(value)) {
                            errInfo.add(columnName + "不能为空");
                            break;
                        }
                        if (value.length() > 50) {
                            errInfo.add(columnName + "值超出最多输入字符限制");
                            break;
                        }
                        //值不能含有特殊符号
                        if (!RegexUtils.checkSpecoalSymbols(value)) {
                            errInfo.add(columnName + "值不能含有特殊符号");
                            break;
                        }
                        //组织不通过
                        if (!checkOrganizeIdPass) {
                            break;
                        }
                        String thisOrganizeId = (String) realMap.get("organizeId");
                        //库里重复
                        long fullNameCount = allPositionList.stream().filter(t -> t.getOrganizeId().equals(thisOrganizeId) && t.getFullName().equals(value)).count();
                        if (fullNameCount > 0) {
                            errInfo.add(columnName + "值已存在");
                            break;
                        }
                        //表格内重复
                        fullNameCount = addList.stream().filter(t -> t.getOrganizeId().equals(thisOrganizeId) && t.getFullName().equals(value)).count();
                        if (fullNameCount > 0) {
                            errInfo.add(columnName + "值已存在");
                            break;
                        }
                        break;
                    case "enCode":
                        if (StringUtil.isEmpty(value)) {
                            errInfo.add(columnName + "不能为空");
                            break;
                        }
                        if (value.length() > 50) {
                            errInfo.add(columnName + "值超出最多输入字符限制");
                            break;
                        }
                        if(!RegexUtils.checkEnCode(value)){
                            errInfo.add(columnName + "只能输入英文、数字和小数点且小数点不能放在首尾");
                            break;
                        }
                        //库里重复
                        long enCodeCount = allPositionList.stream().filter(t -> t.getEnCode().equals(value)).count();
                        if (enCodeCount > 0) {
                            errInfo.add(columnName + "值已存在");
                            break;
                        }
                        //表格内重复
                        enCodeCount = addList.stream().filter(t -> t.getEnCode().equals(value)).count();
                        if (enCodeCount > 0) {
                            errInfo.add(columnName + "值已存在");
                            break;
                        }
                        break;
                    case "type":
                        if (StringUtil.isEmpty(value)) {
                            errInfo.add(columnName + "不能为空");
                            break;
                        }
                        DictionaryDataEntity typeDictionary = typeDictionaryList.stream().filter(t -> t.getFullName().equals(value)).findFirst().orElse(null);
                        if (typeDictionary == null) {
                            errInfo.add("找不到该" + columnName + "值");
                            break;
                        }
                        realMap.put("type", typeDictionary.getEnCode());
                        break;
                    case "sortCode":
                        if (StringUtil.isEmpty(value)) {
                            realMap.put("sortCode", 0);
                            break;
                        }
                        Long numValue = 0l;
                        try {
                            numValue = Long.parseLong(value);
                        } catch (Exception e) {
                            errInfo.add(columnName + "值不正确");
                            break;
                        }
                        if (numValue < 0) {
                            errInfo.add(columnName + "值不能小于0");
                            break;
                        }
                        if (numValue > 1000000) {
                            errInfo.add(columnName + "值不能大于999999");
                            break;
                        }
                        break;
                    case "enabledMark":
                        if (StringUtil.isEmpty(value)) {
                            errInfo.add(columnName + "不能为空");
                            break;
                        }
                        if ("启用".equals(value)) {
                            realMap.put("enabledMark", 1);
                        } else if ("禁用".equals(value)) {
                            realMap.put("enabledMark", 0);
                        } else {
                            errInfo.add(columnName + "值不正确");
                        }
                        break;
                    default:
                        break;
                }

            }
            if (errInfo.length() == 0) {
                PositionEntity positionEntity = JsonUtil.getJsonToBean(realMap, PositionEntity.class);
                positionEntity.setCreatorTime(new Date());
                addList.add(positionEntity);
            } else {
                eachMap.put("errorsInfo", errInfo.toString());
                failList.add(eachMap);
            }
        }
    }

    private CheckResult checkOrganizeId(String organizeName, Map<String, Object> allOrgsTreeName) {
        for (String key : allOrgsTreeName.keySet()) {
            Object o = allOrgsTreeName.get(key);
            if (organizeName.equals(o.toString())) {
                String[] split = key.split(",");
                return new CheckResult(true, null, split[split.length - 1]);
            }
        }
        return new CheckResult(false, "所属组织不正确", null);
    }

    /**
     * 获取下拉框
     *
     * @return
     */
    private Map<String, String[]> getOptionMap() {
        Map<String, String[]> optionMap = new HashMap<>();
        //岗位类型
        List<DictionaryDataEntity> typeList = dictionaryDataService.getByTypeCodeEnable(DictionaryDataEnum.POSITION_TYPE.getDictionaryTypeId());
        String[] type = typeList.stream().map(DictionaryDataEntity::getFullName).toArray(String[]::new);
        optionMap.put("type", type);
        //状态
        optionMap.put("enabledMark", new String[]{"启用", "禁用"});
        return optionMap;
    }
}
